package br.com.conhecimento.core.util;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

public class DateUtil {

	public static long diff(Date start, Date end) {

		Calendar startCalendar = Calendar.getInstance(TimeZone.getTimeZone("pt_BR"));
		startCalendar.setTimeInMillis(start.getTime());

		Calendar endCalendar = Calendar.getInstance(TimeZone.getTimeZone("pt_BR"));
		endCalendar.setTimeInMillis(end.getTime());

		long diff = endCalendar.getTimeInMillis() - startCalendar.getTimeInMillis();

		int timestampOfDay = 1000 * 60 * 60 * 24;

		long diffDays = diff / timestampOfDay;

		return diffDays;
	}
	
	public static long diffHoras(Timestamp start, Timestamp end) {

		Calendar startCalendar = Calendar.getInstance(TimeZone.getTimeZone("pt_BR"));
		startCalendar.setTimeInMillis(start.getTime());

		Calendar endCalendar = Calendar.getInstance(TimeZone.getTimeZone("pt_BR"));
		endCalendar.setTimeInMillis(end.getTime());

		long diff = endCalendar.getTimeInMillis() - startCalendar.getTimeInMillis();

		int timestampOfDay = 1000 * 60 * 60;

		long diffDays = diff / timestampOfDay;

		return diffDays;
	}
	
	public static boolean isValidDate(String inDate) {
		if (inDate == null) {
			return false;
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
		if (inDate.trim().length() != dateFormat.toPattern().length()) {
			return false;
		}
		dateFormat.setLenient(false);
		try {
			dateFormat.parse(inDate.trim());
		} catch (ParseException pe) {
			return false;
		}
		return true;
	}
	
	
	public static boolean validaDataInicialMaiorFinal(Date dataCorrente, Date dataFinal) {	
		Calendar dataInicial = Calendar.getInstance();
		dataInicial.setTime(dataCorrente);
		long dataInicialMilis = dataInicial.getTimeInMillis();
		
		Calendar dataFim = Calendar.getInstance();
		dataFim.setTime(dataFinal);
		long dataFimMilis = dataFim.getTimeInMillis();
		
		if(dataInicialMilis >= dataFimMilis) {
			return true;
		}
		
		return false;
	}
	
	public static Date retornaDataHora(Date data, int hora, int minuto, int segundo) {
		
		Calendar dataAtual = Calendar.getInstance();
		dataAtual.setTime(data);
		
		Calendar dataInicial = Calendar.getInstance();
		dataInicial.set(dataAtual.get(Calendar.YEAR), dataAtual.get(Calendar.MONTH), dataAtual.get(Calendar.DAY_OF_MONTH), hora, minuto, segundo);
		
		return dataInicial.getTime();
	}
	
	public static int obtemDiferencaDias(Timestamp dataInicial, Date dataFinal) throws Exception {
		return obtemDiferencaDias(getDate(dataInicial), dataFinal);
	}	
	
	public static int obtemDiferencaDias(Date dataInicial, Date dataFinal) throws Exception {

		int diferencaDias = 0;

		try {

			dataInicial = obtemDataInicial(dataInicial);
			dataFinal = obtemDataInicial(dataFinal);

			if (dataInicial.before(dataFinal)) {
				Calendar cDataInicial = new GregorianCalendar();
				cDataInicial.setTime(dataInicial);

				while (cDataInicial.getTime().before(dataFinal)) {
					diferencaDias++;
					cDataInicial.add(Calendar.DATE, 1);
				}
				return diferencaDias; 

			} else if (dataInicial.after(dataFinal)) {
				Calendar cDataFinal = new GregorianCalendar();
				cDataFinal.setTime(dataFinal);

				while (dataInicial.after(cDataFinal.getTime())) {
					diferencaDias++;
					cDataFinal.add(Calendar.DATE, 1);
				}
				return diferencaDias * -1; 

			} else {
				return diferencaDias;
			}

		} catch (Exception e) {
			throw e;
		}
	}
	
	public static Date obtemDataInicial(Date data) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(data);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}
	
	public static Date getDate(String data) throws ParseException{
		return new SimpleDateFormat("dd/MM/yyyy").parse(data);
	}
	
	public static Date getDate(Timestamp data) throws ParseException{
		if (data != null) {
			return new Date(data.getTime());
		}else{
			return null;
		}
	}	
	
	/**
	 * Formatar data no formato dd/MM/yyyy
	 * @param data
	 * @return
	 */
	public static String formataData(Date data) {
		if(data != null){
			return new SimpleDateFormat("dd/MM/yyyy").format(data);
		}else{
			return "";
		}
	}
	
	/**
	 * Formatar data no formato dd/MM/yyyy
	 * @param data
	 * @return
	 */
	public static String formataData(Date data, String mask) {
		if(data != null){
			return new SimpleDateFormat(mask).format(data);
		}else{
			return "";
		}
	}
	
	/**
	 * Formatar data no formato dd/MM/yyyy
	 * @param data
	 * @return
	 */
	public static String formataDataDDMMYY(Date data) {
		if(data != null){
			return new SimpleDateFormat("dd/MM/yy").format(data);
		}else{
			return "";
		}
	}
	/**
	 * Formatar data no formato dd/MM
	 * @param data
	 * @return
	 */
	public static String formataDiaEMes(Date data) {
		if(data != null){
			return new SimpleDateFormat("dd/MM").format(data);
		}else{
			return "";
		}
	}
	/**
	 * Formatar data no formato dd/MM/yyyy HH:mm
	 * @param data
	 * @return
	 */
	public static String formataDataHora(Date data) {
		if(data != null){
			return new SimpleDateFormat("dd/MM/yyyy HH:mm").format(data);
		}else{
			return "";
		}
	}	
	public static String formataDataHoraSegundo(Date data) {
		if(data != null){
			return new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(data);
		}else{
			return "";
		}
	}	
	public static Date getDataHoraSegundo(String data) throws ParseException {
		if(data != null){
			return new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").parse(data);
		}else{
			return null;
		}
	}
	
	/**
	 * Formatar data no formato dd/MM/yyyy HH:mm
	 * @param data
	 * @return
	 */
	public static String formataDiaHora(Date data) {
		if(data != null){
			return new SimpleDateFormat("dd '/' HH:mm").format(data);
		}else{
			return "";
		}
	}

	/**
	 * Verifica se a data é válida
	 * @param data
	 * @return
	 */
	public static boolean dataValida(String data) {
		if(data == null){
			return false;
		}else{
			if(data.replaceAll("_", "").length() != 10){
				return false;
			}
		}
		try {

			return isValidDate(data);
		} catch (Exception e) {
			return false;
		}
	}


	/**
	 * Verifica se a data (mm/yyyy) é válida
	 * @param mesAno
	 * @return
	 */
	public static boolean mesAnoValido(String mesAno) {
		try {
			getDate("01/" + mesAno);
		} catch (Exception e) {
			return false;
		}
		return true;
	}


	/**
	 * Verifica se a data (mm/yyyy) é válida
	 * @param mesAno
	 * @return
	 */
	public static Date getData(String mesAno, int dia) {
		try {

			String diaStr = String.valueOf(dia);
			if (dia < 10) {
				diaStr = " " + diaStr;
			}
			return getDate(diaStr + "/" + mesAno);
		} catch (Exception e) {
			return null;
		}
	}	


	/**
	 * formata hora
	 * @param data
	 * @return
	 */
	public static String formataHora(Date data) {
		if(data != null){
			return new SimpleDateFormat("HH:mm:ss").format(data);
		}else{
			return "";
		}
	}

}
